package com.example.demo.controller;

import com.alibaba.excel.util.DateUtils;
import com.fasterxml.jackson.databind.exc.InvalidFormatException;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.openxml4j.exceptions.OpenXML4JException;
import org.apache.poi.openxml4j.opc.TargetMode;
import org.apache.poi.util.Units;
import org.apache.poi.xwpf.usermodel.*;
import org.apache.xmlbeans.XmlException;
import org.openxmlformats.schemas.drawingml.x2006.main.CTGraphicalObject;
import org.openxmlformats.schemas.drawingml.x2006.wordprocessingDrawing.CTAnchor;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTDrawing;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.io.*;
import java.text.ParseException;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 测试电子签字、盖章、生成印章Controller
 *
 * @author xiaobeibei@gogpay.cn
 * @date 2023-07-08 14:40
 */
@RestController
@RequestMapping("/sign")
public class DemoController {

    public static void main(String[] args) throws IOException, InvalidFormatException, FileNotFoundException, OpenXML4JException, ParseException {
        // 模板文件路径
        String templatePath = "C:\\Users\\Administrator\\Desktop\\temp (2).docx";
        // 输出文件路径
        String outputPath = "C:\\Users\\Administrator\\Desktop\\output.docx";
        // 图片文件路径
        String imagePath = "C:\\Users\\Administrator\\Desktop\\img0.jpg";
////        // 读取模板
        InputStream is = new FileInputStream(templatePath);
        XWPFDocument doc = new XWPFDocument(is);


        Iterator<IBodyElement> bodyElementsIterator = doc.getBodyElementsIterator();
        int curT = 0;//当前表格元素操作对象的索引
        int curP = 0;//当前段落元素操作对象的索引
        while (bodyElementsIterator.hasNext()) {
            IBodyElement next = bodyElementsIterator.next();
            String text = next.getBody().getParagraphArray(curP).getText();
            if (text.contains("结构构造措施检测")) {
                String text1 = next.getBody().getParagraphArray(curP + 1).getText();
                // 排除空行
                if (text1.trim().isEmpty()) {
                    text1 = next.getBody().getParagraphArray(curP + 2).getText();
                }
                if (text1.contains("构造柱") && text1.contains("圈梁") && text1.contains("门窗过梁")) {
                    if (text1.contains("拉结钢筋") || text1.contains("拉结筋")) {
                        System.out.println("到这了");
                    }
                }
            }
            if (text.contains("现场检测照片")) {
                XWPFTable table = next.getBody().getTableArray(curT);
                if (table == null || table.getRows().isEmpty() || table.getRows().get(0).getCell(0) == null) {
                    System.out.println("报告中缺少现场检测照片");
                }
            }
            if (text.contains("上部主体结构检测")){
                String text1 = next.getBody().getParagraphArray(curP + 1).getText();
                System.out.println(text1);
            }
            if (text.contains("委托信息")){
                XWPFTable table = next.getBody().getTableArray(curT);
                String tableText = table.getText();
                if (!tableText.contains("委托单位")||!tableText.contains("委托日期")){
                    System.out.println("报告中缺少委托信息");
                }else {
                    String pattern = "\\d{4}年\\d{2}月\\d{2}日";
                    Pattern r = Pattern.compile(pattern);
                    Matcher m = r.matcher(tableText);
                    if (m.find()){
                        System.out.println("委托日期："+m.group());
                        if (m.group().contains("年")) {
                            String replace = m.group().replace("年", "-").replace("月", "-").replace("日", "");
                            LocalDate parse = LocalDate.parse(replace, DateTimeFormatter.ISO_DATE);
                            System.out.println(parse);
                        }
                    }
                }
            }

            // todo getEmbeddedPictures() 获取的是当前段落紧跟的图片 如果获取后面图片(即当前段落序号需要 +1)
            // todo 那我想获取当前段落紧接的上一张图片就是当前段落序号 -1
            //  显然word文档图片元素也属于BodyElementType.PARAGRAPH类型
            // todo  runs是指当前段落的运行  一个运行是指文档中上下连续的文本，它可能跨越不同的样式（如果当前段落前面为空行，则没有run）
            if (text.contains("结构简图") || text.contains("结构计算书") || text.contains("验算图")) {
                List<XWPFRun> runs = next.getBody().getParagraphArray(curP - 1).getRuns();
                if (!runs.isEmpty()){
                    List<XWPFPicture> embeddedPictures = runs.get(0).getEmbeddedPictures();
                    String text1 = runs.get(0).getText(0);
                    if (embeddedPictures.isEmpty()) {
                        System.out.println("没有计算书");
                    }
                }else {
                    System.out.println(text+"没有计算书");
                }
            }

            if (BodyElementType.PARAGRAPH.equals(next.getElementType())) {
                curP++;
            }
            if (BodyElementType.TABLE.equals(next.getElementType())) {
                curT++;
            }

        }


        boolean flag = false;
        for (int i = 0; i < doc.getParagraphs().size(); i++) {
            XWPFParagraph xwpfParagraph = doc.getParagraphs().get(i);
            if (xwpfParagraph.getText().contains("鉴定类别：")) {
                XWPFParagraph xwpfParagraph1 = doc.getParagraphs().get(i + 2);
                if (xwpfParagraph1.getRuns().isEmpty() || xwpfParagraph1.getRuns().size() == 0) {
                    XWPFRun run = xwpfParagraph1.createRun();
                    run.addPicture(new FileInputStream(imagePath), XWPFDocument.PICTURE_TYPE_PNG, imagePath, Units.toEMU(120), Units.toEMU(120)); // 插入图片
                    // 2. 获取到图片数据
                    CTDrawing drawing = run.getCTR().getDrawingArray(0);
                    CTGraphicalObject graphicalobject = drawing.getInlineArray(0).getGraphic();
                    //拿到新插入的图片替换添加CTAnchor 设置浮动属性 删除inline属性
                    CTAnchor anchor = getAnchorWithGraphic(graphicalobject, "QrImg" + 1,
                            Units.toEMU(100), Units.toEMU(100),//图片大小
                            Units.toEMU(11), Units.toEMU(11), false);//相对当前段落位置 需要计算段落已有内容的左偏移
                    drawing.setAnchorArray(new CTAnchor[]{anchor});//添加浮动属性
                    drawing.removeInline(0);//删除行内属性
                } else {
                    for (XWPFRun run : xwpfParagraph1.getRuns()) {
                        run.addPicture(new FileInputStream(imagePath), XWPFDocument.PICTURE_TYPE_PNG, imagePath, Units.toEMU(120), Units.toEMU(120)); // 插入图片
                        // 2. 获取到图片数据
                        CTDrawing drawing = run.getCTR().getDrawingArray(0);
                        if (drawing.getInlineArray().length > 0) {
                            CTGraphicalObject graphicalobject = drawing.getInlineArray(0).getGraphic();
                            //拿到新插入的图片替换添加CTAnchor 设置浮动属性 删除inline属性
                            CTAnchor anchor = getAnchorWithGraphic(graphicalobject, "QrImg" + 1,
                                    Units.toEMU(100), Units.toEMU(100),//图片大小
                                    Units.toEMU(11), Units.toEMU(11), false);//相对当前段落位置 需要计算段落已有内容的左偏移
                            drawing.setAnchorArray(new CTAnchor[]{anchor});//添加浮动属性
                            drawing.removeInline(0);//删除行内属性
                            break;
                        }
                    }
                }
                flag = true;
            }
        }

        // 输出文件
//        FileOutputStream out = new FileOutputStream(outputPath);
//        doc.write(out);
//        out.close();
        doc.close();
        is.close();
    }

    /**
     * 图片替换
     *
     * @param document  操作文档
     * @param imagePath 二维码地址
     * @param rid       文档被替换图片rid
     */

    private static void replaceImg(XWPFDocument document, String imagePath, String rid) {
        String ind = "";
        //已经改好了不用动了。
        try {
            document.getPackagePart().removeRelationship(rid);//删除原有空白图片
            ind = document.addPictureData(new FileInputStream(imagePath),
                    XWPFDocument.PICTURE_TYPE_PNG);//在word插入一张没有关系的图片数据
            //将新插入的图片关系替换到模板图片上，替换的只是图片数据，大小位置还是原来模板的
            document.getPackagePart().addRelationship(document.getPackagePart().
                            getRelationship(ind).getTargetURI(), TargetMode.INTERNAL,
                    XWPFRelation.IMAGES.getRelation(), rid);
        } catch (org.apache.poi.openxml4j.exceptions.InvalidFormatException | FileNotFoundException e) {
            e.printStackTrace();
            System.out.println("替换图片失败");
        }
    }

    /**
     * @param ctGraphicalObject 图片数据
     * @param deskFileName      图片描述
     * @param width             宽
     * @param height            高
     * @param leftOffset        水平偏移 left
     * @param topOffset         垂直偏移 top
     * @param behind            文字上方，文字下方
     * @return
     * @throws Exception
     */
    private static CTAnchor getAnchorWithGraphic(CTGraphicalObject ctGraphicalObject,
                                                 String deskFileName, int width, int height,
                                                 int leftOffset, int topOffset, boolean behind) {
        System.out.println(">>width>>" + width + "; >>height>>>>" + height);
//        String anchorXML =
//                "<wp:anchor xmlns:wp=\"http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing\" "
//                        + "simplePos=\"0\" relativeHeight=\"0\" behindDoc=\"" + ((behind) ? 1 : 0) + "\" locked=\"0\" layoutInCell=\"1\" allowOverlap=\"1\">"
//                        + "<wp:simplePos x=\"0\" y=\"0\"/>"
//                        + "<wp:positionH relativeFrom=\"column\">"
//                        + "<wp:posOffset>" + leftOffset + "</wp:posOffset>"
//                        + "</wp:positionH>"
//                        + "<wp:positionV relativeFrom=\"paragraph\">"
//                        + "<wp:posOffset>" + topOffset + "</wp:posOffset>" +
//                        "</wp:positionV>"
//                        + "<wp:extent cx=\"" + width + "\" cy=\"" + height + "\"/>"
//                        + "<wp:effectExtent l=\"0\" t=\"0\" r=\"0\" b=\"0\"/>"
//                        + "<wp:wrapNone/>"
//                        + "<wp:docPr id=\"1\" name=\"Drawing 0\" descr=\"" + deskFileName + "\"/><wp:cNvGraphicFramePr/>"
//                        + "</wp:anchor>";50165 h1099185
        String anchorXML =
                "<wp:anchor xmlns:wp=\"http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing\" "
                        + "distT=\"0\" distB=\"0\" distL=\"0\" distR=\"0\" simplePos=\"0\" relativeHeight=\"251658240\" behindDoc=\"0\" locked=\"0\" layoutInCell=\"1\" allowOverlap=\"1\">"
                        + "<wp:simplePos x=\"0\" y=\"0\"/>"
                        + "<wp:positionH relativeFrom=\"column\">"
                        + "<wp:posOffset>100000</wp:posOffset>" + "</wp:positionH>" +
                        "<wp:positionV relativeFrom=\"paragraph\">" +
                        "<wp:posOffset>50165</wp:posOffset>" + "</wp:positionV>" +
                        "<wp:extent cx=\"1400000\" cy=\"1400000\"/>" +
                        "<wp:effectExtent l=\"0\" t=\"0\" r=\"0\" b=\"0\"/>" + "<wp:wrapNone/>\n" +
                        "<wp:docPr id=\"112\" name=\"图片 112\" descr=\"QrImg\"/>" + "<wp:cNvGraphicFramePr/>" +
                        "</wp:anchor>";
        CTDrawing drawing = null;
        try {
            drawing = CTDrawing.Factory.parse(anchorXML);
        } catch (XmlException e) {
            e.printStackTrace();
        }
        assert drawing != null;
        CTAnchor anchor = null;
        if (drawing.getAnchorArray().length > 0) {
            anchor = drawing.getAnchorArray(0);
            anchor.setGraphic(ctGraphicalObject);
        }
        return anchor;
    }

}
